/*
 * Copyright (c) 2020-2021, SERI Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-06-23     Lyons        first version
 */

#ifndef __DATADEF_H__
#define __DATADEF_H__

#ifndef __linux__
#error "Not Support on Non-Linux Platform!"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <pthread.h>
#ifdef __linux__
#include <curses.h>
#include <termios.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#else
#include <conio.h>
#endif // #ifdef __linux__

/**
  * @brief Select Instruction Set
  */

#define RV32M

/**
  * @brief Select Peripheral
  */

// #define ENABLE_TIMER
// #define ENABLE_UART
// #define ENABLE_LCD

/**
  * @brief Define Memory Size, Byte
  */

#define MEMORY_SIZE             (512 * 1024)

/**
  * @brief Define Array/Struct Operate Macro
  */

#define CLEAR_ARRAY(ins,data)   memset((uint8_t*)&ins,data,sizeof(ins))
#define CLEAR_STRUCT(ins,data)  memset((uint8_t*)&ins,data,sizeof(ins))

#define GET_ARRAY_NUM(ins)      ((uint32_t)(sizeof(ins)/sizeof(ins[0])))
#define GET_STRUCT_SIZE(ins)    ((uint32_t)(sizeof(ins)))

/**
  * @brief Redefine Data Type
  */

typedef unsigned    long int    uint64_t;
typedef unsigned    int         uint32_t;
typedef unsigned    short       uint16_t;
typedef unsigned    char        uint8_t;

typedef signed      long int    int64_t;
typedef signed      int         int32_t;
typedef signed      short       int16_t;
typedef signed      char        int8_t;

/**
  * @brief Define Bit Operate Macro
  */

#define SHIFT_R(data,n)         ( (uint32_t)(data) >> (n) )
#define SHIFT_L(data,n)         ( (uint32_t)(data) << (n) )

#define BIT(data,n)             ( SHIFT_R(data,n) & 0x1 )

#define ZERO_EXTEND(data,n)     ( (data) & SHIFT_R(-1,32-n) )
#define SIGN_EXTEND(data,n)     ( ZERO_EXTEND(data,n) + (BIT(data,n-1) ? ~SHIFT_R(-1,32-n) : 0) )

#define DATA_MASK(data,m,s)     ( SHIFT_R(data,s) & ~SHIFT_L(-1,m) )

/**
  * @brief Define Custom Data Type
  */

typedef enum
{
    eMemorySize_Null,

    eMemorySize_Byte,
    eMemorySize_HalfWord,
    eMemorySize_Word,

    eMemorySize_Max
} MemorySize_t;

typedef enum
{
    eMemoryExtType_Zero,
    eMemoryExtType_Sign,

    eMemoryExtType_Max
} MemoryExtType_t;

typedef struct
{
    uint32_t                    size;
    uint32_t                    buf[32];
} Regfile_t;

typedef struct
{
    uint32_t                    size;
    uint32_t                    buf[4096];
} Csrfile_t;

typedef struct
{
    uint32_t                    size;
    uint32_t                    buf[MEMORY_SIZE/4];
} Memory_t;

typedef struct
{
    uint32_t                    inst;

    uint8_t                     rs1;    // 5-bits
    uint8_t                     rs2;    // 5-bits
    uint8_t                     rd;     // 5-bits
    uint32_t                    imm;
    uint32_t                    csr;    // 12-bits
    uint8_t                     shamt;  // 5-bits

    uint32_t                    rs1_data;
    uint32_t                    rs2_data;
    uint32_t                    rd_data;
    uint32_t                    csr_data;

    uint32_t (*exec)(void*);

    uint32_t                    mem_addr;
    uint32_t                    mem_data;
    uint8_t                     mem_we;
    uint8_t                     mem_rd;
    MemoryExtType_t             mem_ext;
    MemorySize_t                mem_size;

    uint32_t                    mret;

    uint32_t                    current_pc;
    uint32_t                    next_pc;
} InstInfo_t;

typedef struct
{
    char                        name[8];

    uint32_t                    address;
    uint32_t                    size;

    Memory_t                    *memory;
} MemoryMap_t;

/**
  * @brief Define Shell Command Buffer Max Length, Byte
  */

#define SHELL_CMD_SIZE          (128)

/**
  * @brief Define Debug Operate Macro
  */

#define DEBUG_D                 printf

// #define DEBUG_ISA

// #define DEBUG_PRINT_PC
// #define DEBUG_PRINT_TRACE

#endif //#ifndef __DATADEF_H__
